public class PLDebug {
	private static PLDebug mDBG;

	private boolean mDbgMode;
	
	private boolean mLogEnable;
	private boolean mInfoEnable;
	private boolean mErrEnable;
	private boolean mWarnEnable;
	
	private PLDebug() {
		SetDbgMode(false); 
	}

	public static synchronized PLDebug Obj() {
		if (mDBG == null) {
			mDBG = new PLDebug();
		}
		return mDBG;
	}

	private void UpdateLogLevels() {
		mErrEnable = true;
		mWarnEnable = true;

		if (mDbgMode) {
			mLogEnable = true;
			mInfoEnable = true;
		} else {		
			mLogEnable = false;
			mInfoEnable = false;
		}
	}

	private static void PrintFuncInfo() {		
		StackTraceElement [] callStack = new Throwable().getStackTrace();
		System.out.print(callStack[2].getClassName() + "." +
						callStack[2].getMethodName() + ":" + 
						callStack[2].getLineNumber() + ": ");
	}

	// no cloning allowed
	public Object clone() throws CloneNotSupportedException {
		throw new CloneNotSupportedException();
	}

	static void Log(String format, Object... objects) {
		if (PLDebug.Obj().IsLoggingEnabled()) {
			PrintFuncInfo();
			System.out.println(String.format(format, objects));
		}
	}

	static void Info(String format, Object... objects) {
		if (PLDebug.Obj().IsInfoEnabled()) {
			PrintFuncInfo();
			System.out.println(String.format(format, objects));
		}
	}

	static void Warn(String format, Object... objects) {
		if (PLDebug.Obj().IsWarningingEnabled()) {
			PrintFuncInfo();
			System.out.println(String.format(format, objects));
		}
	}

	static void Err(String format, Object... objects) {
		if (PLDebug.Obj().IsErrEnabled()) {
			PrintFuncInfo();
			System.out.println(String.format(format, objects));
		}
	}

	public boolean IsLoggingEnabled() {
		return mLogEnable;
	}
	public void EnableLogging(boolean enable) {
		mLogEnable = enable;
	}

	public boolean IsInfoEnabled() {
		return mInfoEnable;
	}
	public void EnableInfo(boolean enable) {
		mInfoEnable = enable;
	}

	public boolean IsWarningingEnabled() {
		return mWarnEnable;
	}
	public void EnableWarning(boolean enable) {
		mWarnEnable = enable;
	}

	public boolean IsErrEnabled() {
		return mErrEnable;
	}
	public void EnableErr(boolean enable) {
		mErrEnable = enable;
	}

	
	public void SetDbgMode(boolean dbg_mode) {
		mDbgMode = dbg_mode;
		UpdateLogLevels();
	}

}
